#include <glib.h>

gint global_count = 0;
GRWLock *global_rwlock = NULL;

static gpointer _thread_once_func(gpointer data)
{
    g_print("Will be called only once! \n");

    return GINT_TO_POINTER(9999);
}

static gint _thread_inner_init_func(void)
{
    static GOnce my_once = G_ONCE_INIT;

    g_once(&my_once, _thread_once_func, NULL);

    g_print("g_once retval: %d \n", GPOINTER_TO_INT(my_once.retval));

    return my_once.status;
}

static gpointer _thread_inc_func(gpointer data)
{
    gint i = 0;
    gint status = 0;

    status = _thread_inner_init_func();
    g_print("%s: status %d \n", __FUNCTION__, status);

    g_rw_lock_reader_lock(global_rwlock);
    global_count ++;
    g_rw_lock_reader_unlock(global_rwlock);
}

static gpointer _thread_dec_func(gpointer data)
{
    gint i = 0;
    gint status = 0;

    status = _thread_inner_init_func();
    g_print("%s: status %d \n", __FUNCTION__, status);

    g_rw_lock_reader_lock(global_rwlock);
    global_count --;
    g_rw_lock_reader_unlock(global_rwlock);
}

void test_thread_once(void)
{
    GThread *th1,*th2;

    global_rwlock = g_new0(GRWLock, 1);

    g_print("\n");

    g_rw_lock_init(global_rwlock);
    th1 = g_thread_new("th1", _thread_inc_func, NULL);
    th2 = g_thread_new("th2", _thread_dec_func, NULL);
    g_thread_join(th1);
    g_thread_join(th2);
    g_rw_lock_clear(global_rwlock);
    g_free(global_rwlock);
}

gint main(gint argc, gchar **argv)
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/thread/once", test_thread_once);

    return g_test_run();
}